package com.java8.lambda;

import com.java8.lambda.impl.impl.MyFun;
import org.junit.Test;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 一.Lambda表达式的基础语法: Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或Lambda操作符
 *                          箭头操作符将Lambda表达式拆分为两部分:
 *                              左侧: Lambda表达式的参数列表
 *                              右侧: Lambda表达式所需要执行的功能，即Lambda体。
 *
 * Lambda只能使用在函数式接口上，函数式接口是只有一个抽象方法的接口，称为函数式接口。
 *
 * 语法格式一: 无参数,无返回值
 *      () -> System.out.println("Hello");
 *
 *
 * 语法格式二: 有一个参数,并无返回值
 *          (x) -> System.out.println(x);
 *
 * 语法格式三: 有一个参数,小括号可以不写
 *          x -> System.out.println(x);
 *
 * 语法格式四: 有两个以上的参数，并且Lambda体中有多条语句
 *          Comparator<Integer> comparator1 = (o1, o2) -> {
 *             return Integer.compare(o1, o2);
 *           };
 *
 * 语法格式五:若Lambda表达体中只有一条语句，return和大括号都可以省略不写。
 *          Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
 *
 * 语法格式六:Lambda表达式的参数列表的数据类型可以省略不写，因为JVM编译器可以通过上下文推断出，数据类型,即"类型推断"。
 *
 *
 * 上联:左右遇一括号省。
 * 下联:左侧推断类型省
 * 横批:能省则省
 *
 *
 * 二.Lambda表达式需要"函数式接口"的支持
 *      函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用注解@FunctionInterface 修饰
 *                可以检查是否是函数式接口
 */
public class TestLambda2 {

    @Test
    public void test1() {


        int num = 0;  //jdk 1.8以前必须是final，jdk1.8时，不用加final,但是本质依然是final修饰的不可变常量。


        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                //如果在jdk1.8以前，局部内部类使用了同级别的变量，该变量必须是final修饰
                System.out.println("Hello World!" + num);
            }
        };

        runnable.run();

        System.out.println("---------------------------");

        Runnable runnable1 = () -> System.out.println("Hello Lambda");

        runnable1.run();
    }


    @Test
    public void test2() {

        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {

            }
        };

        Consumer<String> consumer1 = (x) -> System.out.println(x);
        consumer1.accept("尚硅谷");

        Consumer<String> consumer2 = x -> System.out.println(x);
        consumer2.accept("尚硅谷");
    }

    @Test
    public void test3() {
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return 0;
            }
        };

        Comparator<Integer> comparator1 = (o1, o2) -> {
            return Integer.compare(o1, o2);
        };
    }

    @Test
    public void test4() {
        Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
    }


    @Test
    public void test5() {
        String[] str = {"aaa", "bbb", "ccc"};
        //类型推断的实例，泛型可以不写
        show(new HashMap<>());
    }

    public void show(Map<String, Integer> map) {

    }

    //需求:对一个数进行运算
    @Test
    public void test6() {
        Integer operation = operation(100, x -> x * x);
        System.out.println(operation);
    }

    public Integer operation(Integer num, MyFun myFun) {
        return myFun.getValue(num);
    }

}
